home *** CD-ROM | disk | FTP | other *** search
/ Graphics Plus / Graphics Plus.iso / general / visulztn / saoimage / saoimage.lha / panctrl.c < prev    next >
C/C++ Source or Header  |  1990-04-20  |  9KB  |  276 lines

  1. #ifndef lint
  2. static char SccsId[] = "%W%  %G%";
  3. #endif
  4.  
  5. /* Module:    panctrl.c (Pan Control)
  6.  * Purpose:    Respond to inputs which control pan and zoom
  7.  * Subroutine:    control_pan()            returns: void
  8.  * Subroutine:    select_pan()            returns: void
  9.  * Xlib calls:    XSync();
  10.  * Copyright:    1989 Smithsonian Astrophysical Observatory
  11.  *        You may do anything you like with this file except remove
  12.  *        this copyright.  The Smithsonian Astrophysical Observatory
  13.  *        makes no representations about the suitability of this
  14.  *        software for any purpose.  It is provided "as is" without
  15.  *        express or implied warranty.
  16.  * Modified:    {0} Michael VanHilst    initial version         31 May 1989
  17.  *        {n} <who> -- <does what> -- <when>
  18.  */
  19.  
  20. #include <stdio.h>        /* define stderr, NULL, etc. */
  21. #include <X11/Xlib.h>        /* X window stuff */
  22. #include <X11/Xutil.h>        /* window manager stuff */
  23. #include "hfiles/constant.h"    /* define codes */
  24. #include "hfiles/define.h"    /* define MIN, MAX, etc */
  25. #include "hfiles/struct.h"    /* all struct record types */
  26. #include "hfiles/extern.h"    /* major declared structs */
  27.  
  28. /*
  29.  * Subroutine:    control_pan
  30.  * Purpose:    Respond to mouse commands in pan mode
  31.  */
  32. void control_pan ( )
  33. {
  34.   static int moved = 0;
  35.   static int buttons = 0;
  36.   static int downbutton = -1;
  37.   static int oldmode = ZOP;
  38.   float bufx, bufy;
  39.   Bool statedmotion_in_disp();        /* Function for XCheckIfEvent */
  40.   void i_transform(), d_transform(), draw_scope(), set_tdisp(), reset_tdisp();
  41.   void panedge_zoom(), new_pancursor(), new_display(), show_dispcoords();
  42.   void print_table(), draw_magnifier();
  43.  
  44.   /* if mouse button pressed (and no others), start tracking */
  45.   switch( control.event.type ) {
  46.   case ButtonPress:
  47.     /* check for patch request */
  48.     if( control.event.xbutton.button == Button3 ) {
  49.       print_table();
  50.       if( control.event.xbutton.state & ShiftMask ) {
  51.     i_transform(&coord.pantoimg, control.event.xbutton.x,
  52.             control.event.xbutton.y, &bufx, &bufy);
  53.     d_transform(&coord.imgtobuf, (double)bufx, (double)bufy,
  54.             &bufx, &bufy);
  55.     draw_magnifier((double)bufx, (double)bufy);
  56.       }
  57.       return;
  58.     } else if( (control.event.xbutton.button != Button1) &&
  59.            (control.event.xbutton.button != Button2) )
  60.       return;
  61. #ifdef DEBUG
  62.     if( (buttons <0) || (buttons > 1) ) {
  63.       (void)fprintf(stderr, "Lost track of panning buttons: %d\n",buttons);
  64.       buttons = 1;
  65.     }
  66. #endif
  67.     buttons++;
  68.     /* set up variables for interactive mode */
  69.     downbutton = control.event.xbutton.button;
  70.     /* if second button, no added set-up, don't respond till move */
  71.     if( buttons > 1 ) {
  72.       return;
  73.     }
  74.     /* store mode (may be called from other mode) */
  75.     oldmode = control.mode;
  76.     control.mode = ZOP;
  77.     /* set filter for events we will track on priority basis */
  78.     control.priority =
  79.       MotionNotify | ButtonPress | ButtonRelease | LeaveNotify;
  80.     /* continue into moved type response */
  81.   case MotionNotify:
  82.     /* we must be tracking a button to do the this */
  83.     if( downbutton < 0 )
  84.       return;
  85.     /* must be mouse moved - call relevant cursor activity */
  86.     if( control.event.xmotion.window == dispbox.ID ) {
  87.       /* get only the most recent move */
  88.       XSync(control.event.xmotion.display, 0);
  89.       while( XCheckIfEvent(control.event.xmotion.display, &control.event,
  90.                statedmotion_in_disp,
  91.                (char *)(&control.event.xmotion.state)) );
  92.       /* if moved outside the window, cancel tracking */
  93.       if( (control.event.xmotion.x < 0) ||
  94.       (control.event.xmotion.x >= dispbox.width) ||
  95.       (control.event.xmotion.y < 0) ||
  96.       (control.event.xmotion.y >= dispbox.height) ) {
  97.     /* clear image change mark */
  98.     moved = 0;
  99.     buttons = 0;
  100.     downbutton = -1;
  101.     reset_tdisp(&coord);
  102.     new_pancursor(1);
  103.     /* unset tracking priority and mode */
  104.     control.mode =  oldmode;
  105.     control.priority = 0;
  106.     return;
  107.       }
  108.       switch( downbutton ) {
  109.       case Button1:
  110.     /* case pan - transform center to img coordinates */
  111.     i_transform(&coord.disptoimg,
  112.             control.event.xmotion.x, control.event.xmotion.y,
  113.             &coord.tid.cenX, &coord.tid.cenY);
  114.     moved = 1;
  115.     break;
  116.       case Button2:
  117.     /* case zoom - transform edge to img coordinates and choose a zoom */
  118.     panedge_zoom(&coord, &coord.disptoimg,
  119.              control.event.xmotion.x, control.event.xmotion.y);
  120.     moved = 1;
  121.     break;
  122.       default:
  123.     break;
  124.       }
  125.     } else if( control.event.xbutton.window == panbox.ID ) {
  126.       /* get only the most recent move */
  127.       while( XCheckWindowEvent(panbox.display, panbox.ID, ButtonMotionMask,
  128.                    &control.event) );
  129.       switch( downbutton ) {
  130.       case Button1:
  131.     /* case pan - transform center to image coordinates */
  132.     i_transform(&coord.pantoimg,
  133.             control.event.xmotion.x, control.event.xmotion.y,
  134.             &coord.tid.cenX, &coord.tid.cenY);
  135.     moved = 1;
  136.     break;
  137.       case Button2:
  138.     /* case zoom - transform edge to img coordinates and choose a zoom */
  139.     panedge_zoom(&coord, &coord.pantoimg,
  140.              control.event.xmotion.x, control.event.xmotion.y);
  141.     moved = 1;
  142.     break;
  143.       default:
  144.     break;
  145.       }
  146.       if( control.event.xbutton.state & ShiftMask ) {
  147.     i_transform(&coord.pantoimg, control.event.xmotion.x,
  148.             control.event.xmotion.y, &bufx, &bufy);
  149.     d_transform(&coord.imgtobuf, (double)bufx, (double)bufy,
  150.             &bufx, &bufy);
  151.     draw_magnifier((double)bufx, (double)bufy);
  152.       }
  153.     }
  154.     /* keep the center coords within the image */
  155.     if( coord.tid.cenX < coord.img.X1 )
  156.       coord.tid.cenX = coord.img.X1 + 0.001;
  157.     else if( coord.tid.cenX > coord.img.X2 )
  158.       coord.tid.cenX = coord.img.X2 - 0.001;
  159.     if( coord.tid.cenY < coord.img.Y1 )
  160.       coord.tid.cenY = coord.img.Y1 + 0.001;
  161.     else if( coord.tid.cenY > coord.img.Y2 )
  162.       coord.tid.cenY = coord.img.Y2 - 0.001;
  163.     /* set needed parameters for proposed display parameters */
  164.     set_tdisp(&coord);
  165.     /* draw panbox cursor */
  166.     new_pancursor(1);
  167.     break;
  168.   case ButtonRelease:
  169.     /* act only if this button is the last trackable button */
  170.     if( control.event.xbutton.button  == Button3 )
  171.       return;
  172.     if( (buttons <= 0) || (--buttons > 0) )
  173.       return;
  174.     downbutton = -1;
  175.     /* redraw the cursor correctly if we have been Xor'ing */
  176.     if( color.cursor_overlay == 0 )
  177.       new_pancursor(0);
  178.     if( moved == 0 )
  179.       return;
  180.     /* prepare and display new image */
  181.     new_display(1, 0, 0, 0);
  182.     if( control.verbose ) {
  183.       /* report disp coordinates to user */
  184.       show_dispcoords();
  185.     }
  186.     /* clear image change mark */
  187.     moved = 0;
  188.     /* unset tracking priority */
  189.     control.mode =  oldmode;
  190.     control.priority = 0;
  191.     break;
  192.   case LeaveNotify:
  193.     /* leaving the window undo's any selection activity */
  194.     if( downbutton != -1 ) {
  195.       buttons = 0;
  196.       downbutton = -1;
  197.       reset_tdisp(&coord);
  198.       new_pancursor(0);
  199.     }
  200.     /* clear image change mark */
  201.     moved = 0;
  202.     /* unset tracking priority and mode */
  203.     control.mode =  oldmode;
  204.     control.priority = 0;
  205.     break;
  206.   }
  207. }
  208.  
  209. /*
  210.  * Subroutine:    select_pan
  211.  * Purpose:    Respond to a menu selection in the pan and zoom menu
  212.  * Xlib calls:    XSync();
  213.  */
  214. void select_pan ( )
  215. {
  216.   float zoom;
  217.   void reset_tdisp(), set_tdisp(), new_pancursor(), new_display();
  218.   void show_dispcoords();
  219.  
  220.   if( control.response[0] != ZOP )
  221.     return;
  222.   control.mode = ZOP;
  223.   switch( control.response[1] ) {
  224.     /* main menu selections have 0, change only main mode */
  225.   case 0:
  226.     return;
  227.   case ZOP_ZPan14:
  228.     zoom = coord.id.zoom * 0.25;
  229.     break;
  230.   case ZOP_ZPan12:
  231.     zoom = coord.id.zoom * 0.5;
  232.     break;
  233.   case ZOP_ZPan1:
  234.     zoom = 1;
  235.     break;
  236.   case ZOP_ZPan2:
  237.     zoom = coord.id.zoom * 2.0;
  238.     break;
  239.   case ZOP_ZPan4:
  240.     zoom = coord.id.zoom * 4.0;
  241.     break;
  242.   case ZOP_Center:
  243.     /* center on image (same zoom) */
  244.     coord.tid.cenX = coord.img.cenX;
  245.     coord.tid.cenY = coord.img.cenY;
  246.     zoom = coord.id.zoom;
  247.     break;
  248.   default:
  249.     (void)fprintf(stderr,"Unknown menu zoom factor!\n");
  250.     return;
  251.   }
  252.   /* check against the limits before proceeding */
  253.   if( (0.01 > zoom) || (zoom > 400.0) ) {
  254.     (void)fprintf(stderr, "WARNING: Attempt to exceed zooming limits!\n");
  255.     reset_tdisp(&coord);
  256.   }
  257.   /* tid.zoom = zoom but force exact integer alignment (int or 1/int) */
  258.   if( zoom > 0.75 )
  259.     coord.tid.zoom = (double)((int)(zoom + 0.5));
  260.   else
  261.     coord.tid.zoom = 1.0 / (double)((int)((1.0 / zoom) + 0.5));
  262.   /* calculate new display coordinates (in CoordTemp.c) */
  263.   set_tdisp(&coord);
  264.   /* create and draw new panbox cursor */
  265.   new_pancursor(0);
  266.   /* make sure this stuff appears before doing anything else */
  267.   XSync(panbox.display, 0);
  268.   /* prepare and display new image */
  269.   new_display(1, 0, 0, 0);
  270.   /* update record and report status */
  271.   if( control.verbose ) {
  272.     /* report disp coordinates to user */
  273.     show_dispcoords();
  274.   }
  275. }
  276.